package com.laiketui.plugin.common.service.plugin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.laiketui.plugin.common.domain.MainVo;
import com.laiketui.plugin.common.domain.auction.AuctionProductModel;
import com.laiketui.plugin.common.domain.auction.AuctionSessionModel;
import com.laiketui.plugin.common.domain.auction.AuctionSpecialModel;
import com.laiketui.plugin.common.domain.base.User;
import com.laiketui.plugin.common.domain.lktconst.DictionaryConst;
import com.laiketui.plugin.common.domain.lktconst.ErrorCode;
import com.laiketui.plugin.common.domain.vo.AddStockVo;
import com.laiketui.plugin.common.domain.vo.auction.AddGoodsVo;
import com.laiketui.plugin.common.exceotion.LaiKeApiWarnException;
import com.laiketui.plugin.common.interfaces.PublicStockService;
import com.laiketui.plugin.common.interfaces.PubliceService;
import com.laiketui.plugin.common.interfaces.plugin.PublicAuctionService;
import com.laiketui.plugin.common.mapper.*;
import com.laiketui.plugin.common.tool.DataUtils;
import com.laiketui.plugin.common.tool.DateUtil;
import com.laiketui.plugin.common.tool.data.GoodsDataUtils;
import com.laiketui.plugin.common.tool.str.StringUtils;
import com.laiketui.core.exception.LaiKeAPIException;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * 公共竞拍方法
 *
 * @author Trick
 * @date 2022/7/1 17:58
 */
@Service
public class PublicAuctionServiceImpl implements PublicAuctionService {

    private final Logger logger = LoggerFactory.getLogger(PublicAuctionServiceImpl.class);

    @Autowired
    private AuctionSpecialModelMapper auctionSpecialModelMapper;

    @Autowired
    private AuctionSessionModelMapper auctionSessionModelMapper;

    @Autowired
    private AuctionProductModelMapper auctionProductModelMapper;

    @Autowired
    private PubliceService publiceService;

    @Autowired
    private ConfiGureModelMapper confiGureModelMapper;

    @Autowired
    private PublicStockService publicStockService;

    @Override
    public int getStatus(String id) throws LaiKeAPIException {
        int status = AuctionSpecialModel.AuctionStatus.STATUS_NOT_STARTED;
        try {
            AuctionSpecialModel auctionSpecialOld = auctionSpecialModelMapper.selectByPrimaryKey(id);
            if (auctionSpecialOld == null || auctionSpecialOld.getRecovery().equals(DictionaryConst.ProductRecycle.RECOVERY)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_SJBCZ, "数据不存在");
            }
            //当前时间大于截至时间 未开始
            if (DateUtil.dateCompare(new Date(), auctionSpecialOld.getStart_date())) {
                //当前时间大于结束时间 已结束
                if (!DateUtil.dateCompare(auctionSpecialOld.getEnd_date(), new Date())) {
                    logger.debug("专场活动id:{} 已标记结束", id);
                    status = AuctionSpecialModel.AuctionStatus.STATUS_END_STARTED;
                } else {
                    logger.debug("专场活动id:{} 已标记开始", id);
                    status = AuctionSpecialModel.AuctionStatus.STATUS_STARTED;
                }
            } else {
                logger.debug("专场活动id:{} 已标记未开始", id);
            }
            AuctionSpecialModel auctionSpecialUpdate = new AuctionSpecialModel();
            auctionSpecialUpdate.setId(id);
            auctionSpecialUpdate.setStatus(status);
            logger.debug("专场活动id:{} 状态是否变更:{}", id, auctionSpecialModelMapper.updateByPrimaryKeySelective(auctionSpecialUpdate) > 0);
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("获取专场活动状态 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "getStatus");
        }
        return status;
    }

    @Override
    public int getStatusBySession(String id) throws LaiKeAPIException {
        int status = AuctionSpecialModel.AuctionStatus.STATUS_NOT_STARTED;
        try {
            AuctionSessionModel auctionSessionOld = auctionSessionModelMapper.selectByPrimaryKey(id);
            if (auctionSessionOld == null || auctionSessionOld.getRecovery().equals(DictionaryConst.ProductRecycle.RECOVERY)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_SJBCZ, "数据不存在");
            }
            //判断专场是否开始,只有专场开始了场次才做判断
            int specialStatus = getStatus(auctionSessionOld.getSpecial_id());
            if (AuctionSpecialModel.AuctionStatus.STATUS_STARTED.equals(specialStatus)) {
                //当前时间大于结束时间 已结束
                if (!DateUtil.dateCompare(auctionSessionOld.getEnd_date(), new Date())) {
                    logger.debug("场次活动id:{} 已标记结束", id);
                    status = AuctionSessionModel.AuctionStatus.STATUS_END_STARTED;
                } else if (DateUtil.dateCompare(new Date(), auctionSessionOld.getStart_date())) {
                    logger.debug("场次活动id:{} 已标记开始", id);
                    status = AuctionSessionModel.AuctionStatus.STATUS_STARTED;
                } else {
                    logger.debug("场次活动id:{} 已标记未开始", id);
                }
            } else if (AuctionSpecialModel.AuctionStatus.STATUS_END_STARTED.equals(specialStatus)) {
                status = AuctionSessionModel.AuctionStatus.STATUS_END_STARTED;
            }
            AuctionSessionModel auctionSessionUpdate = new AuctionSessionModel();
            auctionSessionUpdate.setId(id);
            auctionSessionUpdate.setStatus(status);
            logger.debug("场次活动id:{} 状态是否变更:{}", id, auctionSessionModelMapper.updateByPrimaryKeySelective(auctionSessionUpdate) > 0);
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("获取场次活动状态 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "getStatusBySession");
        }
        return status;
    }

    @Override
    public String getStatusName(int status) throws LaiKeAPIException {
        String statusName = "未开始";
        try {
            if (AuctionSpecialModel.AuctionStatus.STATUS_STARTED.equals(status)) {
                statusName = "进行中";
            } else if (AuctionSpecialModel.AuctionStatus.STATUS_END_STARTED.equals(status)) {
                statusName = "已结束";
            }
            return statusName;
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("获取活动状态名称 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "getStatusName");
        }
    }

    @Override
    public String getStatusNameBySession(int status) throws LaiKeAPIException {
        String statusName = "未开始";
        try {
            if (AuctionSessionModel.AuctionStatus.STATUS_STARTED.equals(status)) {
                statusName = "进行中";
            } else if (AuctionSessionModel.AuctionStatus.STATUS_END_STARTED.equals(status)) {
                statusName = "已结束";
            }
            return statusName;
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("获取场次活动状态 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "getStatusNameBySession");
        }
    }

    @Override
    public String getGoodsStatusName(int status) throws LaiKeAPIException {
        String statusName = "待拍卖";
        try {
            if (AuctionProductModel.GoodsStatus.STATUS_SOLD_IN_PROGRESS.equals(status)) {
                statusName = "拍卖中";
            } else if (AuctionProductModel.GoodsStatus.STATUS_SOLD.equals(status)) {
                statusName = "已拍卖";
            } else if (AuctionProductModel.GoodsStatus.STATUS_UNSOLD.equals(status)) {
                statusName = "已流拍";
            }
            return statusName;
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("获取商品状态 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "getGoodsStatusName");
        }
    }

    @Override
    public Map<String, Object> getSessionGoods(MainVo vo, String specialId, String sessionId) throws LaiKeAPIException {
        Map<String, Object> resultMap = new HashMap<>(16);
        try {
            return getSessionGoods(vo, specialId, sessionId, null);
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("根据场次id获取下面的商品 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "getSessionGoodsList");
        }
    }

    @Override
    public Map<String, Object> getSessionGoods(MainVo vo, String specialId, String sessionId, Map<String, Object> sessionParmaMap) throws LaiKeAPIException {
        Map<String, Object> resultMap = new HashMap<>(16);
        try {
            List<Map<String, Object>> sessionResultList = new ArrayList<>();
            Map<String, Object> parmaSessionMap = new HashMap<>(16);
            if (sessionParmaMap != null && !sessionParmaMap.isEmpty()) {
                parmaSessionMap.putAll(sessionParmaMap);
            }
            if (StringUtils.isNotEmpty(specialId)) {
                parmaSessionMap.put("special_id", specialId);
            }
            if (StringUtils.isNotEmpty(sessionId)) {
                parmaSessionMap.put("id", sessionId);
            }
            parmaSessionMap.put("store_id", vo.getStoreId());
            parmaSessionMap.put("is_show", DictionaryConst.WhetherMaven.WHETHER_OK);
            parmaSessionMap.put("add_date_sort", DataUtils.Sort.DESC.toString());
            List<Map<String, Object>> sessionList = auctionSessionModelMapper.selectAuctionSessionList(parmaSessionMap);
            for (Map<String, Object> sessionMap : sessionList) {
                Map<String, Object> sessionResultMap = new HashMap<>(16);
                sessionResultMap.put("sessionId", MapUtils.getString(sessionMap, "id"));
                //场次名称
                sessionResultMap.put("sessionName", MapUtils.getString(sessionMap, "sessionName"));
                //获取场次下的商品
                List<Map<String, Object>> goodsResultList = new ArrayList<>();
                int total = auctionProductModelMapper.countGoodsJoinConfigureById(vo.getStoreId(), MapUtils.getString(sessionMap, "id"));
                List<Map<String, Object>> goodsList;
                if (total > 0) {
                    String priceSort = DataUtils.Sort.DESC.toString();
                    if (sessionParmaMap != null && !sessionParmaMap.isEmpty()) {
                        if (parmaSessionMap.containsKey("priceSort")) {
                            priceSort = MapUtils.getString(sessionParmaMap, "priceSort");
                        }
                    }
                    goodsList = auctionProductModelMapper.getGoodsJoinConfigureById(vo.getStoreId(), MapUtils.getString(sessionMap, "id"), priceSort, 0, 10);
                    for (Map<String, Object> goodsMap : goodsList) {
                        Map<String, Object> goodsResultMap = new HashMap<>(16);
                        goodsResultMap.put("img", publiceService.getImgPath(MapUtils.getString(goodsMap, "img"), vo.getStoreId()));
                        goodsResultMap.put("id", MapUtils.getString(goodsMap, "id"));
                        goodsResultMap.put("acId", MapUtils.getString(goodsMap, "acId"));
                        //如果当前出价为空则获取起拍价
                        BigDecimal currentPrice = new BigDecimal(MapUtils.getString(goodsMap, "price"));
                        goodsResultMap.put("price", currentPrice);
                        goodsResultMap.put("goodsName", MapUtils.getString(goodsMap, "product_title"));
                        goodsResultMap.put("attribute", GoodsDataUtils.getProductSkuValue(MapUtils.getString(goodsMap, "attribute")));
                        //商品是否收藏过
                        goodsResultMap.put("isCollection", MapUtils.getInteger(goodsMap, "collectionId") != null);
                        goodsResultList.add(goodsResultMap);
                    }
                }
                sessionResultMap.put("goods", goodsResultList);
                sessionResultMap.put("total", total);
                sessionResultList.add(sessionResultMap);
            }
            resultMap.put("sessionList", sessionResultList);
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("获取专场下所有商品信息 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "getSessionGoodsList");
        }
        return resultMap;
    }

    @Override
    public boolean isOutAmt(int auctionGoodsId) throws LaiKeAPIException {
        boolean isOutAmt = false;
        try {
            AuctionProductModel auctionProductOld = auctionProductModelMapper.selectByPrimaryKey(auctionGoodsId);
            if (auctionProductOld != null) {
                //更新场次状态
                int status = getStatusBySession(auctionProductOld.getSession_id());
                if (AuctionSessionModel.AuctionStatus.STATUS_STARTED.equals(status)) {
                    isOutAmt = true;
                }
            }
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("当前竞拍商品是否可以出价 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "isOutAmt");
        }
        return isOutAmt;
    }

    @Override
    public void delSpecial(MainVo vo, String id, User user) throws LaiKeAPIException {
        try {
            int row;
            if (StringUtils.isEmpty(id)) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_CSCW, "参数错误");
            }
            int status = this.getStatus(id);
            //进行中的活动不能操作
            if (AuctionSessionModel.AuctionStatus.STATUS_STARTED.equals(status)) {
                throw new LaiKeApiWarnException(ErrorCode.BizErrorCode.PluginAuctionCode.ERROR_CODE_JXZDHDBNCZ, "进行中的活动不能操作");
            }
            AuctionSpecialModel auctionSpecialOld = new AuctionSpecialModel();
            auctionSpecialOld.setStore_id(vo.getStoreId());
            auctionSpecialOld.setId(id);
            auctionSpecialOld = auctionSpecialModelMapper.selectOne(auctionSpecialOld);
            if (auctionSpecialOld == null) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_SJBCZ, "数据不存在");
            }

            AuctionSpecialModel auctionSpecialUpdate = new AuctionSpecialModel();
            auctionSpecialUpdate.setId(id);
            auctionSpecialUpdate.setUpdate_date(new Date());
            auctionSpecialUpdate.setRecovery(DictionaryConst.ProductRecycle.RECOVERY);

            row = auctionSpecialModelMapper.updateByPrimaryKeySelective(auctionSpecialUpdate);
            if (row < 1) {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_CZSB, "操作失败");
            }
            //回滚所有竞拍商品库存
            AuctionSessionModel auctionSessionModel = new AuctionSessionModel();
            auctionSessionModel.setSpecial_id(auctionSpecialOld.getId());
            auctionSessionModel.setRecovery(DictionaryConst.WhetherMaven.WHETHER_NO);
            List<AuctionSessionModel> sessionModels = auctionSessionModelMapper.select(auctionSessionModel);
            for (AuctionSessionModel sessionModel : sessionModels){
                AuctionProductModel auctionProductModel = new AuctionProductModel();
                auctionProductModel.setSession_id(sessionModel.getId());
                auctionProductModel.setRecovery(DictionaryConst.WhetherMaven.WHETHER_NO);
                List<AuctionProductModel> productModels = auctionProductModelMapper.select(auctionProductModel);
                for (AuctionProductModel productModel : productModels){
                    //回滚商品库存
                    AddStockVo addStockVo = new AddStockVo();
                    addStockVo.setStoreId(vo.getStoreId());
                    addStockVo.setId(productModel.getAttr_id());
                    addStockVo.setPid(productModel.getGoods_id());
                    addStockVo.setAddNum(1);
                    addStockVo.setText("删除竞拍商品返还" + 1);
                    publicStockService.addGoodsStock(addStockVo, null);
                }
            }
            //删除场次
            logger.debug("删除专场id={},删除{}个场次", id, auctionSessionModelMapper.delSessionByAuctionId(id));
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("删除专场 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "delSpecial");
        }
    }

    @Override
    public void addGoodsBySessionId(int storeId, String attrJson, String specialId, String sessionId, boolean isDelOldGoods) throws LaiKeAPIException {
        try {
            addGoodsBySessionId(storeId, attrJson, specialId, sessionId, isDelOldGoods, null);
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("删除专场 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "delSpecial");
        }
    }

    @Override
    public void addGoodsBySessionId(int storeId, String attrJson, String specialId, String sessionId, boolean isDelOldGoods, Integer mchId) throws LaiKeAPIException {
        try {
            int row;
            //删除之前场次商品
            if (isDelOldGoods) {
                //回滚竞拍商品库存
                AuctionProductModel auctionProductModel = new AuctionProductModel();
                auctionProductModel.setSession_id(sessionId);
                auctionProductModel.setRecovery(DictionaryConst.WhetherMaven.WHETHER_NO);
                List<AuctionProductModel> select = auctionProductModelMapper.select(auctionProductModel);
                for (AuctionProductModel model : select){
                    //回滚商品库存
                    AddStockVo addStockVo = new AddStockVo();
                    addStockVo.setStoreId(storeId);
                    addStockVo.setId(model.getAttr_id());
                    addStockVo.setPid(model.getGoods_id());
                    addStockVo.setAddNum(1);
                    addStockVo.setText("删除竞拍商品返还" + 1);
                    publicStockService.addGoodsStock(addStockVo, null);
                }
                if (mchId != null) {
                    row = auctionProductModelMapper.delAuctionGoodsBySessionIdByMchId(sessionId, mchId);
                } else {
                    row = auctionProductModelMapper.delAuctionGoodsBySessionId1(sessionId);
                }
                logger.debug("删除之前场次id:{} 商品数量:{}", sessionId, row);
            }
            List<AuctionProductModel> auctionProductSaveList = new ArrayList<>();
            List<AddGoodsVo> attrList = JSON.parseObject(attrJson, new TypeReference<List<AddGoodsVo>>() {
            });
            AuctionSpecialModel auctionSpecialOld = null;
            if (StringUtils.isNotEmpty(specialId)) {
                auctionSpecialOld = auctionSpecialModelMapper.selectByPrimaryKey(specialId);
                if (auctionSpecialOld == null) {
                    throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_SJCW, "数据错误");
                }
            }
            for (AddGoodsVo attr : attrList) {
                int attrId = attr.getAttrId();
                //商品是否参加了其它竞拍场次
                if (auctionSessionModelMapper.isAuctionGoods(new Date(), specialId, sessionId, attrId) > 0) {
                    throw new LaiKeAPIException(ErrorCode.BizErrorCode.PluginAuctionCode.ERROR_CODE_SPYCJHD, "商品已参加活动");
                }
                Integer pid = confiGureModelMapper.getGoodsId(attrId);
                if (pid == null) {
                    throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_SPBCZ, "商品不存在");
                }
                //商品价格
                BigDecimal goodsPrice = confiGureModelMapper.getGoodsPirce(attrId);

                if (auctionSpecialOld != null) {
//                    if (BigDecimal.ZERO.compareTo(new BigDecimal(attr.getStartingAmt())) >= 0) {
//                        attr.setStartingAmt(auctionSpecialOld.getNumber().toString());
//                    }
                    if (BigDecimal.ZERO.compareTo(new BigDecimal(attr.getMarkUpAmt())) >= 0) {
                        attr.setMarkUpAmt(auctionSpecialOld.getMark_up_amt().toString());
                    }
                    //起拍价
                    BigDecimal startingAmt = new BigDecimal(attr.getStartingAmt());
                    //加价幅度
                    BigDecimal markUpAmt = new BigDecimal(attr.getMarkUpAmt());
                    if (BigDecimal.ZERO.compareTo(startingAmt) >= 0) {
                        logger.debug("添加商品时,起拍价为空 获取专场默认设置");
                        //是否百分比
                        boolean isPercentage = auctionSpecialOld.getUnit().equals(AuctionSpecialModel.SpecialUnit.UNIT_PERCENTAGE);
                        if (isPercentage) {
                            attr.setStartingAmt(goodsPrice.multiply(auctionSpecialOld.getNumber().divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP)).toString());
                        } else {
                            attr.setStartingAmt(startingAmt.toString());
                        }
                    }
                    if (BigDecimal.ZERO.compareTo(markUpAmt) >= 0) {
                        logger.debug("添加商品时,加价幅度为空 获取专场默认设置");
                        attr.setMarkUpAmt(markUpAmt.toString());
                    }
                }
                //加价幅度最小0.01
                if (new BigDecimal("0.01").compareTo(new BigDecimal(attr.getMarkUpAmt())) > 0) {
                    attr.setMarkUpAmt("0.01");
                }

                AuctionProductModel auctionProductSave = new AuctionProductModel();
                auctionProductSave.setSession_id(sessionId);
                auctionProductSave.setAttr_id(attrId);
                auctionProductSave.setGoods_id(pid);
                auctionProductSave.setGoods_price(goodsPrice);
                auctionProductSave.setStarting_amt(new BigDecimal(attr.getStartingAmt()));
                auctionProductSave.setMark_up_amt(new BigDecimal(attr.getMarkUpAmt()));
                //默认起拍价
                auctionProductSave.setPrice(auctionProductSave.getStarting_amt());
                auctionProductSave.setStatus(AuctionProductModel.GoodsStatus.STATUS_SOLD_WAIT);
                auctionProductSave.setIs_show(DictionaryConst.WhetherMaven.WHETHER_OK);
                auctionProductSave.setRecovery(DictionaryConst.ProductRecycle.NOT_STATUS);
                auctionProductSave.setAdd_date(new Date());
                auctionProductSaveList.add(auctionProductSave);
                //商品出库
                publicStockService.outStockNum(storeId, pid, attrId, 1, true);
            }
            if (auctionProductSaveList.size() > 0) {
                if (auctionProductModelMapper.insertList(auctionProductSaveList) < 1) {
                    throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_CZSB, "操作失败");
                }
            }
        } catch (LaiKeAPIException l) {
            throw l;
        } catch (Exception e) {
            logger.error("添加商品到场次中 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_WLYC, "网络异常", "delSpecial");
        }
    }
}
